'''
CREATE TABLE name_mapping (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name_type VARCHAR(64), -- 如 student, class, school, team
    name VARCHAR(256)
);

INSERT INTO name_mapping(name_type, name) VALUES('student', 'student_default'),
('class', 'class_default'),('school', 'school_default'),('team', 'team_default');
'''
import threading

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

# 内存缓存 & 加锁
NameCacheDict = {}
NameCacheLock = threading.RLock()

NAME_TYPE_STUDENT = 'student'
NAME_TYPE_CLASS = 'class'
NAME_TYPE_SCHOOL = 'school'
NAME_TYPE_TEAM = 'team'


class NameMapping(db.Model):
    __tablename__ = 'name_mapping'

    id = db.Column(db.Integer, primary_key=True)
    name_type = db.Column(db.String(64), nullable=False)
    name = db.Column(db.String(256), nullable=False)


# def get_name_by_type_from_db(name_type):
#     entry = NameMapping.query.filter_by(name_type=name_type).first()
#
#     if not entry:
#         raise Exception(f'数据库中没有数据! name_type: {name_type}')
#
#     return entry.name

def update_name_by_type_from_db(name_type: str, new_name: str):
    """
    根据 name_type 更新数据库中的 name，并通知 etcd 更新缓存
    """
    entry = NameMapping.query.filter_by(name_type=name_type).first()

    if not entry:
        raise Exception(f'数据库中没有数据! name_type: {name_type}')

    entry.name = new_name
    db.session.commit()
    print(f"[DB] Updated name_type={name_type}, new_name={new_name}")


def get_name_by_type(name_type):
    """
    从内存获取，如果未加载则加载一次
    """
    print('get_name_by_type中的NameCacheDict:>>> ', id(NameCacheDict), NameCacheDict)
    if not NameCacheDict:
        with NameCacheLock:
            load_all_names_from_db()

    name = NameCacheDict.get(name_type)
    if name is None:
        raise Exception(f'数据库中没有数据! name_type: {name_type}')
    return name


def refresh_name_cache():
    """
    暴露一个手动刷新缓存的入口
    """
    print('refresh_name_cache start !!!!!!!!!!!!!')
    load_all_names_from_db()
    print('refresh_name_cache finish !!!!!!!!!!!!', id(NameCacheDict), NameCacheDict)


def load_all_names_from_db():
    """
    加载所有 name_type:name 到内存
    """
    global NameCacheDict

    with NameCacheLock:
        # 这里的sql查询可以根据实际情况修改 我这里获取的是全量的数据
        result = NameMapping.query.all()

        NameCacheDict = {entry.name_type: entry.name for entry in result}
